#include <gtest\gtest.h>
#include <gmock\gmock.h>
#include <string>
#include <boost\assign.hpp>
#include <connection\registry.h>
#include "..\mock\session_mock.h"

namespace cs
{

namespace constant 
{
	const address session_addr_1 = 1;
	const address session_addr_2 = 2;
	const address session_addr_3 = 3;

	const std::string service_name("dummy_service");
	const std::string service_name_2("dummy_service2");
}

TEST(ut_registry, add_remove_session)
{
	registry reg;
	registry::session_ptr session_1( new session_mock());
	registry::session_ptr session_2( new session_mock());
	address session_addr_1, session_addr_2;

	session_addr_1 = reg.add_session(session_1);
	session_addr_2 = reg.add_session(session_2);

	EXPECT_EQ(session_addr_1, constant::session_addr_1);
	EXPECT_EQ(session_addr_2, constant::session_addr_2);

	EXPECT_TRUE(reg.find_session(session_addr_1).get() == session_1.get());
	EXPECT_TRUE(reg.find_session(session_addr_2).get() == session_2.get());
	EXPECT_FALSE(reg.find_session(constant::session_addr_3));

	reg.remove_session(session_1);
	EXPECT_FALSE(reg.find_session(constant::session_addr_1));
}

TEST(ut_registry, register_service_OK)
{
	registry reg;
	registry::session_ptr session_1( new session_mock());
	reg.add_session(session_1);

	EXPECT_TRUE(reg.register_service(session_1, constant::service_name));
	EXPECT_EQ(reg.get_service_address(constant::service_name), constant::session_addr_1);

	reg.remove_session(session_1);
	EXPECT_FALSE(reg.find_session(constant::session_addr_1));
	EXPECT_EQ(reg.get_service_address(constant::service_name), 0);
}

TEST(ut_registry, register_service_NOK)
{
	registry reg;
	registry::session_ptr session_1( new session_mock());

	EXPECT_FALSE(reg.register_service(session_1, constant::service_name));

	reg.add_session(session_1);

	EXPECT_TRUE(reg.register_service(session_1, constant::service_name));
	EXPECT_FALSE(reg.register_service(session_1, constant::service_name));
}

TEST(ut_registry, subscribe_service_OK)
{
	registry reg;
	registry::session_ptr session_1( new session_mock());
	registry::session_ptr session_2( new session_mock());
	
	EXPECT_EQ(reg.subscribe_sevice(session_2, constant::service_name), 0);

	reg.add_session(session_1);
	reg.add_session(session_2);

	EXPECT_TRUE(reg.register_service(session_1, constant::service_name));
	EXPECT_EQ(reg.subscribe_sevice(session_2, constant::service_name), constant::session_addr_1);
	EXPECT_EQ(reg.subscribe_sevice(session_2, constant::service_name), 0);

	reg.remove_session(session_2);
	EXPECT_EQ(reg.subscribe_sevice(session_2, constant::service_name), 0);
}

TEST(ut_registry, get_subscribers)
{
	registry reg;
	registry::session_ptr session_1( new session_mock());
	registry::session_ptr session_2( new session_mock());
	registry::session_ptr session_3( new session_mock());

	registry::subscriber_list_t expected_list = boost::assign::list_of
		(session_1) (session_2) (session_3);
	registry::subscriber_list_t expected_list_2 = boost::assign::list_of
		(session_1);

	reg.add_session(session_1);
	reg.add_session(session_2);
	reg.add_session(session_3);

	reg.subscribe_sevice(session_1, constant::service_name);
	reg.subscribe_sevice(session_1, constant::service_name_2);
	reg.subscribe_sevice(session_2, constant::service_name);
	reg.subscribe_sevice(session_3, constant::service_name);

	EXPECT_THAT(reg.get_subscribers(constant::service_name), expected_list);
	EXPECT_THAT(reg.get_subscribers(constant::service_name_2), expected_list_2);
}

}